package com.pdd.mall.security;

import com.pdd.mall.config.JwtConfig;
import com.pdd.mall.entity.Merchant;
import com.pdd.mall.entity.User;
import com.pdd.mall.service.MerchantService;
import com.pdd.mall.service.UserService;
import com.pdd.mall.util.JwtTokenUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * JWT登录授权过滤器
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Autowired
    @Lazy
    private UserService userService;

    @Autowired
    @Lazy
    private MerchantService merchantService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtConfig jwtConfig;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader(jwtConfig.getHeader());

        try {
            if (StringUtils.hasText(authHeader) && authHeader.startsWith(jwtConfig.getTokenPrefix())) {
                String authToken = authHeader.substring(jwtConfig.getTokenPrefix().length() + 1);
                logger.debug("JWT Token: {}", authToken);

                try {
                    String username = jwtTokenUtil.getUsernameFromToken(authToken);

                    if (StringUtils.hasText(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
                        // 直接查询用户和商家信息，避免通过UserDetailsService导致的循环依赖
                        UserDetails userDetails = null;
                        
                        // 尝试获取用户信息
                        User user = userService.getUserByUsername(username);
                        if (user != null) {
                            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
                            userDetails = new org.springframework.security.core.userdetails.User(
                                user.getUsername(), 
                                user.getPassword(),
                                user.getStatus() == 1,
                                true,
                                true,
                                true,
                                authorities
                            );
                        } else {
                            // 尝试获取商家信息
                            Merchant merchant = merchantService.getMerchantByUsername(username);
                            if (merchant != null) {
                                List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                                authorities.add(new SimpleGrantedAuthority("ROLE_MERCHANT"));
                                userDetails = new org.springframework.security.core.userdetails.User(
                                    merchant.getUsername(),
                                    merchant.getPassword(),
                                    merchant.getStatus() == 1,
                                    true,
                                    true,
                                    true,
                                    authorities
                                );
                            }
                        }

                        if (userDetails != null && jwtTokenUtil.validateToken(authToken, userDetails)) {
                            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                                    userDetails, null, userDetails.getAuthorities());
                            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                            SecurityContextHolder.getContext().setAuthentication(authentication);
                            logger.debug("Authentication successful for: {}", username);
                        } else if (userDetails != null) {
                            logger.warn("Token validation failed for: {}", username);
                        }
                    }
                } catch (Exception e) {
                    logger.error("JWT Token processing error: {}", e.getMessage());
                    // 不抛出异常，让请求继续处理，但不设置认证信息
                }
            }
        } catch (Exception e) {
            logger.error("JWT Authentication filter error: {}", e.getMessage());
        }

        filterChain.doFilter(request, response);
    }
}
